#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   Test_ReportSupportedDTC_phy.py
@Time    :   2024/09/02 13:31:28
@Author  :   YangLiang
@Version :   1.0
@Contact :   yangliang@chengtech.com
@License :   (C)Copyright 2022-2025
@Desc    :   None
'''

# here put the import lib
from commDriver.modbus_plc import *
from gettext import find
from xmlrpc.client import Fault
from pytest_assume.plugin import assume

import pytest
import logging
import time
import requests
from sympy import I
# from sympy import assuming
from commDriver.TS_CAN import *
import allure
import sys
from collections.abc import Iterable

from sqlalchemy import false
import Set_up

sys.dont_write_bytecode = True


class Test_ReportSupportedDTC_phy(object):

    # 物理寻址，默认模式，读取支持的DTC
    @allure.severity('normal')
    @allure.title("Test ReportSupportedDTC by SID 0x19 in default session with physical addressing")
    def test_ReportSupportedDTC_Default_Phy(self, action, Driver):
        iStep = 1
        iStep = Driver['CAN'].restartMRR_Power(Driver, iStep)
        time.sleep(1)
        self.testReportSupportedDTC(Driver, 1)

    # 物理寻址，扩展模式，读取支持的DTC
    @allure.severity('normal')
    @allure.title("Test ReportSupportedDTC by SID 0x19 in extended session with physical addressing")
    def test_ReportSupportedDTC_Extended_Phy(self, action, Driver):
        self.testReportSupportedDTC(Driver, 3)

    def testReportSupportedDTC(self, Driver, session):
        time.sleep(1)
        current_failure = [[0x00, 0x00, 0x00]]
        iStep = 1
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x02, 0x09], [0x59, 0x02, 0x09], session, iStep, False, 'UDS', 'ClearFault')
        iStep = Driver['CAN'].delInitialFailure(iStep, uds_resp)

        # 获取存在的当前故障
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x02, 0x09], [0x59, 0x02, 0x09], 0, iStep, False, 'UDS', 'noClearFault')
        for i in range(3, size, 4):
            current_failure.append(uds_resp[i:i+3])
        historical_failure = [[0x00, 0x00, 0x00]]

        # 检查当前故障状态
        iStep = self.checkFailureStatus(Driver, uds_resp, current_failure, historical_failure, iStep)

        # 设置电压为17v 检查当前故障状态
        iStep = Driver['CAN'].SetVolt(Driver, 17, 1.5, iStep)
        current_failure.append([0x98, 0x7A, 0x17])  # 当前故障list
        historical_failure = [[0x00, 0x00, 0x00]]  # 历史故障list
        iStep = self.checkFailureStatus(Driver, uds_resp, current_failure, historical_failure, iStep)

        # 设置电压为8v 检查当前故障状态
        iStep = Driver['CAN'].SetVolt(Driver, 8, 1.5, iStep)
        current_failure.append([0x98, 0x7A, 0x16])
        current_failure.remove([0x98, 0x7A, 0x17])
        historical_failure = [[0x98, 0x7A, 0x17]]
        iStep = self.checkFailureStatus(Driver, uds_resp, current_failure, historical_failure, iStep)

        # 设置电压为12v 检查当前故障状态
        iStep = Driver['CAN'].SetVolt(Driver, 12, 1.5, iStep)
        current_failure.remove([0x98, 0x7A, 0x16])
        historical_failure = [[0x98, 0x7A, 0x16], [0x98, 0x7A, 0x17]]
        iStep = self.checkFailureStatus(Driver, uds_resp, current_failure, historical_failure, iStep)
        time.sleep(1)
        # 重启产品后，检查故障状态
        iStep = Driver['CAN'].restartMRR_11(Driver, iStep)
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x3E, 0x00], [0x7E, 0x00], session, iStep, False, 'UDS', 'noClearFault')
        historical_failure = [[0x98, 0x7A, 0x16], [0x98, 0x7A, 0x17]]
        iStep = self.checkFailureStatus(Driver, uds_resp, current_failure, historical_failure, iStep)

        # 清除故障后，检查故障状态
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x14, 0xFF, 0xFF, 0xFF], [0x54], 0, iStep, False, 'UDS', 'noClearFault')
        time.sleep(2)
        historical_failure = [0x00, 0x00, 0x00]
        iStep = self.checkFailureStatus(Driver, uds_resp, current_failure, historical_failure, iStep)

    def checkFailureStatus(self, Driver, uds_resp, current_failure, historical_failure, iStep=1):
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x0A], [0x59, 0x0A, 0x09], 0, iStep, False, 'UDS', 'noClearFault')
        respstr = binascii.b2a_hex(bytearray(uds_resp), ' ')
        list = self.split_list_by_size(uds_resp[3:], 4)
        with allure.step(f"Step{iStep} check failure status:{0}".format(respstr)):
            for i in range(len(Set_up.DTC_list)):
                dtcNumber = Set_up.DTC_list[i][0]
                iStartByte = 3 + i * 4

                if dtcNumber in current_failure:
                    dtcNumber = dtcNumber + [0x09]
                elif dtcNumber in historical_failure:
                    dtcNumber = dtcNumber + [0x08]
                else:
                    dtcNumber = dtcNumber + [0x00]

                if (dtcNumber in list):
                    findStatus = True
                else:
                    findStatus = False
                    corrRespStr = binascii.b2a_hex(bytearray(dtcNumber), ' ')
                    logging.error(f'dont find DTC number {corrRespStr}')    
                
                with assume:
                    assert  findStatus == True

                

                # if uds_resp[iStartByte:(4+iStartByte)] != dtcNumber:
                #     actualRespStr = binascii.b2a_hex(bytearray(uds_resp[iStartByte:(4+iStartByte)]), ' ')
                #     corrRespStr = binascii.b2a_hex(bytearray(dtcNumber), ' ')
                #     logging.error(f'{actualRespStr} != {corrRespStr}')
        iStep += 1

        return iStep

    def split_list_by_size(Self, original_list, chunk_size):
        return [original_list[i:i + chunk_size] for i in range(0, len(original_list), chunk_size)]

    # 物理寻址，默认模式，读取支持的DTC

    @allure.severity('normal')
    @allure.title("Test ReportSupportedDTC by SID 0x19 in default session with physical addressing")
    def test_ReportSupportedDTC_Default2_Phy(self, action, Driver):
        iStep = 1
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x14, 0xFF, 0xFF, 0xFF], [0x54], 1, iStep, False, 'UDS', 'noClearFault')
        time.sleep(2)

        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x19, 0x0A], [0x59, 0x0A, 0x09], 0, iStep, False, 'UDS', 'noClearFault')

        respstr = binascii.b2a_hex(bytearray(uds_resp), ' ')
        with allure.step("Step4 Response:{0}".format(respstr)):
            with assume:
                assert uds_resp[0:3] == [0x59, 0x0A, 0x09]

            Totle_DTC_List = list(Set_up.DTC_list_all.values())
            for real_reponse in np.array(uds_resp[3:]).reshape(-1, 4):
                current_DTC = real_reponse[0:3].tolist()
                if (current_DTC in Totle_DTC_List):
                    Totle_DTC_List.remove(current_DTC)
                    logging.info('DTC number had found OK,The DTC is:' +
                                 str(binascii.b2a_hex(bytearray(current_DTC), ' ')))
                    with assume: assert True == True
                else:
                    logging.info('DTC number had not found,The DTC is : ' + str(binascii.b2a_hex(bytearray(current_DTC), ' ')))
                    with assume: assert True == False

            if len(Totle_DTC_List) > 0:
                for a in Totle_DTC_List:
                    logging.info('DTC Number ------' + str(binascii.b2a_hex(bytearray(a), ' ')) + 'not include')
                with assume: assert True == False
            else:
                logging.info('All DTC number had been match')
                with assume: assert True == True
